﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

using Aliphant.Common;
using Aliphant.Mvvm.XEvent.Events;
using Aliphant.Mvvm.XEvent.Events.Base.SubScription;
using Aliphant.Mvvm.XEvent.UI;
using Aliphant.UI.Forms.Notify;

using TestModule.Models;
using TestModule.Models.Stocks;

namespace TestModule.ViewModels
{
    public class WidgetStockViewModel : BindableBase
    {
        private WindowEvent _windowEvent;
        private SubScriptionToken _subscriptionToken1;
        private CancellationTokenSource _cts = new CancellationTokenSource();


        public WidgetStockViewModel()
        {
            _windowEvent = Test.EventAgent.GetEvent<WindowEvent>();
            _subscriptionToken1 = _windowEvent.Subscribe(ReleaseAction, (p) => p.Type == EventType.Action && p.WindowActionType == WindowActionType.Close && p.EventId == EventIds.Release);
            StartRealTimeRefresh();
        }

        #region 属性

        /// <summary>
        /// 监控数据:成交量
        /// </summary>
        private int _turnover = -1;
        public int Turnover { get => _turnover; set => _turnover = value; }

        /// <summary>
        /// 监控数据:价格上限
        /// </summary>
        private double _newUpPrice = -1;
        public double NewUpPrice { get => _newUpPrice; set => _newUpPrice = value; }

        /// <summary>
        /// 监控数据:价格下限
        /// </summary>
        private double _newDownPrice = -1;
        public double NewDownPrice { get => _newDownPrice; set => _newDownPrice = value; }

        /// <summary>
        /// 打开通知
        /// </summary>
        private bool _isSendNotify;
        public bool IsSendNotify { get => _isSendNotify; set => SetProperty(ref _isSendNotify, value); }

        /// <summary>
        /// Tick时间
        /// </summary>
        private string _tickTime = string.Empty;
        public string TickTime { get => _tickTime; set => SetProperty(ref _tickTime, value); }

        /// <summary>
        /// 监控股票代码
        /// </summary>
        private object _enMonitorCode = string.Empty;
        private string _monitorCode = string.Empty;
        public string MonitorCode
        {
            get => _monitorCode;
            set
            {
                SetProperty(ref _monitorCode, value);
                _enMonitorCode = _monitorCode;
            }
        }

        /// <summary>
        /// 监控股票名称
        /// </summary>
        private string _monitorName = string.Empty;
        public string MonitorName { get => _monitorName; set => SetProperty(ref _monitorName, value); }

        /// <summary>
        /// 实时股票数据
        /// </summary>
        private StockDetail _curretStock = new StockDetail();
        public StockDetail CurrentStock { get => _curretStock; set => SetProperty(ref _curretStock, value); }

        /// <summary>
        /// 监控状态
        /// </summary>
        private bool _isMonitor;
        public bool IsMonitor { get => _isMonitor; set => SetProperty(ref _isMonitor, value); }


        #endregion

        /// <summary>
        /// 启动数据刷新
        /// </summary>
        private void StartRealTimeRefresh()
        {
            _cts = new CancellationTokenSource();
            Task.Factory.StartNew(async () =>
            {
                while (!_cts.IsCancellationRequested)
                {
                    string codeStr = (string)_enMonitorCode;
                    if (string.IsNullOrEmpty(codeStr))
                    {
                        continue;
                    }
                    string code = codeStr;
                    if (Regex.IsMatch(codeStr, @"^\d{6}$"))
                    {
                        code = await SearchStockCode(codeStr);
                    }

                    if (string.IsNullOrEmpty(code))
                    {
                        NotifyIconHelper.ShowBalloon("股票代码不存在", "XChatAI", 0, NotifyIconHelper.NotifyLevel.Error);
                        IsMonitor = false;
                        continue;
                    }


                    try
                    {
                        TickTime = DateTime.Now.ToString("HH:mm:ss");

                        string[] paramArr = await QueryCurrentDataAsync(code);
                        if (paramArr.Length == 0)
                        {
                            NotifyIconHelper.ShowBalloon("股票数据获取失败", "XChatAI", 0, NotifyIconHelper.NotifyLevel.Error);
                            IsMonitor = false;
                            break;
                        }
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            CurrentStock.Update(paramArr);
                            MonitorStock(CurrentStock);
                        });
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex);
                    }
                    Thread.Sleep(50);
                }
            });
        }

        /// <summary>
        /// 监控数据
        /// </summary>
        /// <param name="stock"></param>
        private void MonitorStock(StockDetail stock)
        {
            if (!IsSendNotify)
            {
                return;
            }
            if (Turnover != -1 && stock.TimeSharingVol > Turnover)
            {
                NotifyIconHelper.ShowBalloon($"成交量突破{Turnover}", "XChatAI", 0, NotifyIconHelper.NotifyLevel.Warning);
            }
            if (NewUpPrice != -1 && stock.NowPrice >= NewUpPrice)
            {
                NotifyIconHelper.ShowBalloon($"股价突破{NewUpPrice}", "XChatAI", 0, NotifyIconHelper.NotifyLevel.Info);
                NewUpPrice = NewUpPrice + 0.01;
            }
            if (NewDownPrice != -1 && stock.NowPrice <= NewDownPrice)
            {
                NotifyIconHelper.ShowBalloon($"股价跌落{NewDownPrice}", "XChatAI", 0, NotifyIconHelper.NotifyLevel.Error);
                NewDownPrice = NewDownPrice - 0.01;
            }
        }


        #region Api Tool

        /// <summary>
        /// 获取实时股票数据
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public static async Task<string[]> QueryCurrentDataAsync(string code)
        {
            string url = "https://qt.gtimg.cn/q=" + code;

            try
            {
                var content = await TencentHttpGetAsync(url);
                content = content.Split('=')[1].Trim('"');
                var paramArr = content.Split("~");
                return paramArr;
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }

            return [];
        }

        /// <summary>
        /// 搜索股票
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static async Task<string> SearchStockCode(string key)
        {
            string url = "https://smartbox.gtimg.cn/s3/?v=2&t=all&c=1&q=" + key;
            try
            {
                string content = await TencentHttpGetAsync(url);
                content = content.Split('=')[1].Trim('"');
                var paramArr = content.Split("~");

                string cont = paramArr[0];
                string code = paramArr[1];
                return cont + code;
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }
            return string.Empty;
        }

        /// <summary>
        /// 创建请求文本
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns></returns>
        private static string BuildQueryString(Dictionary<string, string> parameters)
        {
            using var content = new FormUrlEncodedContent(parameters);
            return content.ReadAsStringAsync().Result;
        }

        private static async Task<string> HttpGetAsync(string url)
        {
            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Add("Accept", "application/json");
            try
            {
                var response = await client.GetAsync(url);
                if (response.IsSuccessStatusCode)
                {
                    var content = await response.Content.ReadAsStringAsync();
                    return content;
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }
            return string.Empty;
        }

        /// <summary>
        /// 腾讯财经HTTP请求
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private static async Task<string> TencentHttpGetAsync(string url)
        {
            HttpClient client = new HttpClient();
            try
            {
                var response = await client.GetAsync(url);
                if (response.IsSuccessStatusCode)
                {
                    byte[] buffer = await response.Content.ReadAsByteArrayAsync();
                    var content = Encoding.GetEncoding("GBK").GetString(buffer);
                    return content;
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }
            return string.Empty;
        }

        #endregion

        /// <summary>
        /// 释放资源
        /// </summary>
        /// <param name="event"></param>
        private void ReleaseAction(WindowEvent @event)
        {
            Release();
        }

        public void Release()
        {
            _cts.Cancel();
        }
    }
}
